﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XmlStudio.DataLayer;
using XmlStudio.Interfaces;
using XmlStudio.Models.Events;

namespace XmlStudio.Models.Actions {
    internal sealed class RemoveRootWithOneChildAction : XmlModelAction {
        #region Fields
        private BigXmlNodeInternal oldRootNode;
        #endregion

        #region Constructors
        public RemoveRootWithOneChildAction(IXmlModelWithNotifications model, BigXmlNodeInternal rootToRemove)
            : base(model) {
            if(rootToRemove.Parent != null) {
                throw new InvalidOperationException("Node to remove is not a root.");
            }

            if(rootToRemove.TotalChildCount > 1) {
                throw new InvalidOperationException("Cannot remove root element with more than 1 child node.");
            }

            this.oldRootNode = rootToRemove;
        }
        #endregion

        #region Methods
        protected override void ExecuteCore() {
            this.model.Root = oldRootNode.ChildNodes[0];
            var rootInternal = this.model.Root as BigXmlNodeInternal;
            if(rootInternal != null) {
                rootInternal.SetParent(null);
                this.oldRootNode.XmlNode.RemoveChild(rootInternal.XmlNode);
                this.model.SetModified(true);
                //this.model.OnNodeRemoved(new Events.NodeRemovedEventArgs<BigXmlNode>(oldRootNode));
                //this.model.OnRootElementAdded(new Events.RootElementAddedEventArgs<BigXmlNode>(this.model.Root));
                this.model.OnRootElementChanged(new RootElementChangedEventArgs(this.model.Root));
                this.model.OnRawXmlChanged(new RawXmlChangedEventArgs());
                this.model.TotalNodeCount--;
            } else {
                throw new InvalidOperationException("Current node instance wasn't created in this xmlModel.");
            }
        }

        protected override void UnExecuteCore() {
            var currentRoot = this.model.Root as BigXmlNodeInternal;
            if(currentRoot != null) {
                this.model.Root = oldRootNode;
                oldRootNode.XmlNode.AppendChild(currentRoot.XmlNode);
                this.model.SetModified(modelWasModified);
                this.model.TotalNodeCount++;
                //this.model.OnNodeRemoved(new Events.NodeRemovedEventArgs<BigXmlNode>(currentRoot));
                //this.model.OnRootElementAdded(new Events.RootElementAddedEventArgs<BigXmlNode>(this.model.Root));
                this.model.OnRootElementChanged(new RootElementChangedEventArgs(this.model.Root));
                this.model.OnRawXmlChanged(new RawXmlChangedEventArgs());
            } else {
                throw new InvalidOperationException("Current node instance wasn't created in this xmlModel.");
            }
        }
        #endregion
    }
}